Klax (Doom's Gate)
==================
A music improvement to show similarities between thrash metal
soundtracks of two games from the Nineties

Produced by Damian Yerrick in September 2018

Klax's audio driver
-------------------
The audio driver of Tengen's port of _Klax_ to NES heavily uses
hardware sweep and hardware envelopes.  The driver sets up a duty,
volume, and sweep (for detune effect) and lets the hardware trigger
a new note whenever the frequency is rewritten.

I hand-decompiled some of the music sequence processing:
```
u8 cur_channel @0x04F5;
u8 note_ticks_left[] @0x04C7;
u8 cur_note[] @0x04CC;
u16 channel_seq_pos[] @0x04D5;
const u8 durations[] = {1, 2, 4, 8, 16, 32, 64} @0xA000;
const u16 note_freqs[] @0xA30C;

void set_ch_freq(u8 semitone_num) @A2E6;

void play_next_note(void) @A291 {
  ptr_f7 = channel_seq_pos[cur_channel]++;
  Y = *ptr_f7;
  A = Y & 0xE0;
  if (A == 0xE0) {
    A = Y;
    A = func_A179();
    if (A) set_ch_freq(A);
    return;
  }
  note_ticks_left[cur_channel] = durations[A >> 5];
  A = Y & 0x1F;
  if (X != 3 /* noise */) {
    // A2D4
    if (A >= 16) A -= 32;
      A += cur_note[cur_channel];
      cur_note[cur_channel] = A;
      if (A != 1) set_ch_freq(A);
    }
  } else {
    if (A > 16) A |= 0x80;  // loopnoise
    Set noise period to A and trigger
  }
}
```

Thus bits 7-5 are log(note length), and bits 4-0 are a 2's complement
signed interval in semitones to this note.  For example, $62
represents up 2 semitones or a major second (bits 4-0: %00010 or +2)
and 8 frames long (bits 7-5: %011 or 3, and 2^3 = 8).  $9B would mean
down 5 semitones or a perfect fourth (bits 4-0: %11011 or -5) and 16
frames long (bits 7-5: %100 or 4, and 2^4 = 16).  Codes $E0-$FF have
a separate meaning that I haven't bothered to crack, as I did not
need it for this hack.

The motif in Klax
-----------------
This motif appears in two of the six pieces in the _Klax_ soundtrack
by Bügsük (Lx Rudis and Dave O'Riva).

    E, E, F#, E, E, G, E, E
    G#, E, E, A, E, E, Bb, A

Because of limits in pattern-sharing in the driver, there are several
copies of this motif in this bank of the ROM. Two are in "Title"

    A9F9: 60 60 62 7E 60 63 7D 60 64 7C 60 65 7B 60 66 7F

This starts out meaning `same same +M2 -M2 same +m3 -m3 same`, etc.
A CPU read breakpoint at `AA01` triggers halfway through this motif.
A second copy in "Title" starts with `6C 60...` where `6C` means
"go up an octave" but is otherwise identical.

The motif is repeated a few times throughout the music data of
"Caverns of Cthulu" such as at `B17A`.  One copy of the motif in
"Caverns" at `B1BC` changes the intervals to move all of the lowest
notes up an octave:

    60 60 76 6A 60 77 69 60 78 68 60 79 67 60 7A 7F

A CPU read breakpoint at B1C8 catches this one.

Changing it to Doom
-------------------
In Bobby Prince's soundtrack for _Doom_, the piece "At Doom's Gate"
is heard in episode 1 mission 1 (E1M1) "Hangar".  It employs a motif
similar in shape and rhythm to the motif in _Klax_, but upside down.

    E, E, E', E, E, D', E, E
    C', E, E, A#, E, E, B, C

To insert this motif into _Klax_, search for all instances of these
bytes:

    62 7E 60 63 7D 60 64 7C 60 65 7B 60 66 7F

replacing them with these bytes:

    6C 74 60 6A 76 60 68 78 60 66 7A 60 67 61

I left the one with the lowest notes up an octave as is because
it moves in opposite directions anyway.

The IPS patch
-------------
Searching and replacing in a hex editor as described above is enough
to get _Klax_ to sound like _Doom_.  To make this easier, use [Lipx]
or any other IPS patch software to apply "Klax (Doom's Gate).nes.ips"
to your copy of _Klax_.

    $ crc32 "Klax (U).nes"
    755cf043	Klax (U).nes
    $ md5sum "Klax (U).nes"
    f957b5d342a2106afc470577c3412588  Klax (U).nes
    $ sha1sum "Klax (U).nes"
    80a2ea6e52b96506613912ff9a15657a29c9684a  Klax (U).nes
    $ sha256sum "Klax (U).nes"
    d010708d6e4bfd208d9ce0a5ae55a6319700b05d87eabbebc1df5527781773e0  Klax (U).nes

I also decided to change the title of "Caverns of Cthulu" in Options.
This required figuring out a "table" for the character encoding used
on that screen.  It turned out that glyphs are in the same order as
ASCII, with $80-$B9 in _Klax_ corresponding to $21-$5A in ASCII.
Space is $BD.  With "Klax (U).tbl" loaded into FCEUX's hex editor,
I changed the title to `AT_DOOM'S_`/`GATE__`, filling unused parts of
the string with spaces in order not to waste time on pointer hunting.


[Lipx]: https://github.com/kylon/Lipx
